using System;
using System.IO;
using CodePlex.TfsLibrary;
using CodePlex.TfsLibrary.ObjectModel;
using CodePlex.TfsLibrary.RepositoryWebSvc;

namespace CodePlex.CodePlexClientLibrary
{
    public abstract class CheckoutCommand : AuthenticatedCommand
    {
        bool nonRecursive = false;
        int revision = Constants.NullChangesetId;

        [Option("non-recursive", "only check out the root directory", ShortName = "n")]
        public bool NonRecursive
        {
            get { return nonRecursive; }
            set { nonRecursive = value; }
        }

        [Option("revision", "get a specific change set", ShortName = "r")]
        public int Revision
        {
            get { return revision; }
            set { revision = value; }
        }

        public override sealed void Execute()
        {
            string tfsUrl;
            string serverPath;
            string destinationFolder;
            VersionSpec version;

            if (revision == Constants.NullChangesetId)
                version = VersionSpec.Latest;
            else
                version = VersionSpec.FromChangeset(revision);

            GetCheckoutParameters(out tfsUrl, out serverPath, out destinationFolder);
            Engine.Checkout(tfsUrl, serverPath, destinationFolder, !nonRecursive, version, OnSourceItem);
        }

        protected abstract void GetCheckoutParameters(out string tfsUrl,
                                                      out string serverPath,
                                                      out string destinationFolder);

        static void OnSourceItem(SourceItem item,
                                 SourceItemResult result)
        {
            if (result != SourceItemResult.S_Ok)
                ConsoleUtil.PrintCommandError(item.LocalName, result);
            else if (item.LocalName != null)
            {
                string relativeName = CodePlexClientUtil.GetRelativePath(Directory.GetCurrentDirectory(), item.LocalName);

                if (relativeName.Length == 0)
                    relativeName = ".";

                if (item.LocalItemStatus == SourceItemStatus.Unversioned)
                    Console.WriteLine("Won't clobber existing {0}", relativeName);
                else
                    Console.WriteLine("A    {0}", relativeName);
            }
        }
    }
}